package Demo1;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class MyBlockingQueue{
    private String[] elems = null;
    private int front = 0;//队头
    private int rear = 0;//队尾
    private int size = 0;
    private Object locker = new Object();//锁对象


    public MyBlockingQueue (int capacity){
        elems = new String[capacity];
    }
    public void put(String elem) throws InterruptedException {
//        入队列
        synchronized (locker) {
            // 使用 while 循环防止竞争条件
            while (size>= elems.length){
//           队列已满 需要阻塞
                locker.wait();//堵塞中 等待唤醒
            }
            elems[rear] = elem;
            rear = (rear+1)% elems.length;

//            入队列成功 说明此时队列不为空 可以唤醒
            locker.notifyAll();// 可以避免死锁
            size++;
        }
    }
    public String take() throws InterruptedException {
//        出队列
        String elem = null;
        synchronized (locker) {
            // 使用 while 循环防止竞争条件
            while (size == 0){
    //            队列已满 需要堵塞
                locker.wait();//堵塞 等待唤醒
            }
             elem = elems[front];
            front = (front+1)% elems.length;
            size--;

//            出队列成功  说明队列不满 可以唤醒wait()
            locker.notifyAll();//避免死锁

            return elem;
        }
    }
}
public class T25 {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue <String> blockingQueue = new ArrayBlockingQueue<>(1000);

//        生产者
        Thread t1 = new Thread(()->{
            int n = 1;
            while(true){
                try {
                    blockingQueue.put(n+" ");
                    System.out.println("生产元素: "+n);
                    n++;
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
//        消费者
        Thread t2 = new Thread(()->{
            while(true){
                try {
                    String n = blockingQueue.take();
                    System.out.println("消费元素: "+n);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
}
